package gui;

import java.util.Stack;

import org.eclipse.swt.custom.ExtendedModifyEvent;
import org.eclipse.swt.custom.ExtendedModifyListener;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.widgets.Composite;

public class TextViewer extends StyledText {
	private static final int UNDO_LIMIT = 20;
	private Stack<TextChange> changes;
	private boolean ignoreUndo;

	public TextViewer(Composite parent, int style) {
		super(parent, style);
		changes = new Stack<TextChange>();

		addExtendedModifyListener(new ExtendedModifyListener() {
			public void modifyText(ExtendedModifyEvent event) {
				if (!ignoreUndo) {
					TextChange newEdit = new TextChange(event.start, event.length, event.replacedText);

					changes.push(newEdit);

					if (changes.size() > UNDO_LIMIT) {
						changes.remove(0);
					}
				}
			}
		});
	}

	public void undo() {
		if (!changes.empty()) {
			// Get the last change
		      TextChange change = changes.pop();

		      // Set the flag. Otherwise, the replaceTextRange call will get placed
		      // on the undo stack
		      ignoreUndo = true;
		      // Replace the changed text
		      replaceTextRange(change.getStart(), change.getLength(), change.getReplacedText());

		      // Move the caret
		      setCaretOffset(change.getStart());

		      // Scroll the screen
		      setTopIndex(getLineAtOffset(change.getStart()));
		      ignoreUndo = false;
		}
	}
	
	public void remove() {
		int[] selection = getSelectionRanges();
		
		if (selection[1] > 0) {
			replaceTextRange(selection[0], selection[1], "");
		}
	}
	
	public boolean isEmptyUndoList() {
		return changes.empty();
	}
	
	public void clearUndoList() {
		changes.clear();
	}
	
	public void clear() {
		setText("");
	}
}
